// Node-RED Function Node for MQTT Data Saving
// 用于保存MQTT实时数据的结构化存储函数

// 初始化全局数据存储
if (!flow.get('mqttDataStore')) {
    flow.set('mqttDataStore', {});
}

// 从topic中提取tenantId和projectId
function extractIdsFromTopic(topic) {
    // topic pattern: mtic/msg/client/realtime/{tenantId}/{projectId}
    const parts = topic.split('/');
    if (parts.length >= 5) {
        return {
            tenantId: parts[4],
            projectId: parts[5]
        };
    }
    return null;
}

// 保存数据到结构化存储
function saveDataToStore(tenantId, projectId, payload) {
    const dataStore = flow.get('mqttDataStore') || {};
    
    // 确保层级结构存在
    if (!dataStore[tenantId]) {
        dataStore[tenantId] = {};
    }
    if (!dataStore[tenantId][projectId]) {
        dataStore[tenantId][projectId] = {};
    }
    
    // 保存每个propId和对应的val
    for (const [propId, val] of Object.entries(payload)) {
        dataStore[tenantId][projectId][propId] = {
            value: val,
            timestamp: new Date().toISOString(),
            lastUpdate: Date.now()
        };
    }
    
    // 保存回flow context
    flow.set('mqttDataStore', dataStore);
    
    return dataStore[tenantId][projectId];
}

// 主函数 - Node-RED function节点的主体
module.exports = function(msg) {
    try {
        // 获取topic和payload
        const topic = msg.topic;
        const payload = msg.payload;
        
        // 验证数据格式
        if (!topic || !payload || typeof payload !== 'object') {
            node.error('Invalid message format: topic or payload missing/invalid');
            return null;
        }
        
        // 从topic中提取ID
        const ids = extractIdsFromTopic(topic);
        if (!ids) {
            node.error('Invalid topic format: cannot extract tenantId and projectId');
            return null;
        }
        
        const { tenantId, projectId } = ids;
        
        // 保存数据
        const savedData = saveDataToStore(tenantId, projectId, payload);
        
        // 创建返回消息
        const result = {
            topic: topic,
            tenantId: tenantId,
            projectId: projectId,
            savedData: savedData,
            timestamp: new Date().toISOString(),
            messageCount: Object.keys(payload).length
        };
        
        // 输出保存结果
        node.log(`Data saved for tenant: ${tenantId}, project: ${projectId}, props: ${Object.keys(payload).length}`);
        
        return result;
        
    } catch (error) {
        node.error('Error processing MQTT data: ' + error.message);
        return null;
    }
};

// 辅助函数：获取存储的数据
function getStoredData(tenantId, projectId) {
    const dataStore = flow.get('mqttDataStore') || {};
    if (dataStore[tenantId] && dataStore[tenantId][projectId]) {
        return dataStore[tenantId][projectId];
    }
    return null;
}

// 辅助函数：获取所有租户数据
function getAllTenants() {
    const dataStore = flow.get('mqttDataStore') || {};
    return Object.keys(dataStore);
}

// 辅助函数：获取指定租户的所有项目
function getProjectsByTenant(tenantId) {
    const dataStore = flow.get('mqttDataStore') || {};
    if (dataStore[tenantId]) {
        return Object.keys(dataStore[tenantId]);
    }
    return [];
}

// 辅助函数：清理过期数据（可选）
function cleanupOldData(maxAgeMs = 24 * 60 * 60 * 1000) { // 默认24小时
    const dataStore = flow.get('mqttDataStore') || {};
    const now = Date.now();
    let cleanedCount = 0;
    
    for (const tenantId in dataStore) {
        for (const projectId in dataStore[tenantId]) {
            for (const propId in dataStore[tenantId][projectId]) {
                const data = dataStore[tenantId][projectId][propId];
                if (now - data.lastUpdate > maxAgeMs) {
                    delete dataStore[tenantId][projectId][propId];
                    cleanedCount++;
                }
            }
        }
    }
    
    // 保存清理后的数据
    flow.set('mqttDataStore', dataStore);
    
    return cleanedCount;
}

// 导出辅助函数供其他节点使用
module.exports.helpers = {
    getStoredData,
    getAllTenants,
    getProjectsByTenant,
    cleanupOldData
};
